import chalk from 'chalk';
import { Plugin } from './Plugin';
import { compose, Composer } from '../utils/compose';

export class PluginGlobal extends Plugin<Plugin.All> {
  protected readonly globalComposer: Composer;
  protected initialized: boolean = false;
  protected locals: Composer[] = [];

  constructor() {
    super();
    this.globalComposer = compose([]);
    this.use(this.globalComposer);
  }

  // Determine which are global items and which are local items dynamically.
  public compare(plugins: Plugin[]): Composer {
    const composer = compose([]);
    const globals = this.globalComposer.get();

    if (!this.initialized) {
      this.initialized = true;
      this.globalComposer.set([...plugins]);
      composer.set([]);
    } else {
      const diffIndex = globals.findIndex((item, index) => item !== plugins[index]);

      if (diffIndex >= 0) {
        this.globalComposer.set(globals.slice(0, diffIndex));
        composer.set(plugins.slice(diffIndex));

        const fallbackToLocals = globals.slice(diffIndex);

        this.locals.forEach((local) => {
          local.prepend(...fallbackToLocals);
        });

        console.warn(chalk.yellowBright.bold(`[Warning] There are some global plugins fallback to locals, check your code since that's not expected.`));
      } else {
        composer.set(plugins.slice(globals.length));
      }
    }

    this.locals.push(composer);

    return composer;
  }
}
